#include "MysqlOperation.h"

MysqlOperation::MysqlOperation()
{
	m_conn = mysql_init(nullptr);
	//	设置字符集
	mysql_set_character_set(m_conn, "utf8");
}

MysqlOperation::~MysqlOperation()
{
	if (m_conn != nullptr) 
	{
		mysql_close(m_conn);
	}

	//	释放结果集
	free_result();
}

bool MysqlOperation::connect(string user, string passwd, string da_name, string ip, unsigned short port)
{
	//	根据mysql官方提供的api连接数据库
	MYSQL* ptr = mysql_real_connect(m_conn, ip.c_str(), user.c_str(), passwd.c_str(), da_name.c_str(), port, nullptr, 0);
	return ptr != nullptr;
}

bool MysqlOperation::update(string sql)
{
	//	根据mysql官方提供的api更新数据库
	if (mysql_query(m_conn, sql.c_str())) {
		cout << "错误信息：" << mysql_error(m_conn) << endl;
		return false;
	}
	return true;
}

bool MysqlOperation::query(string sql)
{
	//	清空上次的结果数据
	free_result();

	//	查询成功后会存到一个结果集中，需要我们自己拿出来
	if (mysql_query(m_conn, sql.c_str()))
		return false;
	m_res = mysql_store_result(m_conn);
	return true;
}

bool MysqlOperation::next()
{
	if (m_res != nullptr) 
	{
		m_row = mysql_fetch_row(m_res);
		if (m_row != nullptr)
			return true;
	}
	return false;
}

string MysqlOperation::value(int index)
{
	//	获取一列有多少数据，然后返回索引位置的数据
	int row_num = mysql_num_fields(m_res);
	if (index >= row_num || index < 0)
		return string();

	char* val = m_row[index];

	//	由于实际字符可能存在'\0'字符的可能，所以需要获取数据长度
	unsigned long len = mysql_fetch_lengths(m_res)[index];
	return string(val,len);
}

bool MysqlOperation::transaction()
{
	return mysql_autocommit(m_conn, false);
}

bool MysqlOperation::commit()
{
	return mysql_commit(m_conn);
}

bool MysqlOperation::rollback()
{
	return mysql_rollback(m_conn);
}

void MysqlOperation::free_result()
{
	if (m_res)
	{
		mysql_free_result(m_res);
		m_res = nullptr;
	}
}

void MysqlOperation::refresh_alive_time()
{
	m_alive_time = steady_clock::now();
}

long long MysqlOperation::get_alive_time()
{
	//	获取时间
	nanoseconds res = steady_clock::now() - m_alive_time;
	//	将纳秒转换成毫秒
	milliseconds millsec = duration_cast<milliseconds>(res);
	return millsec.count();
}